package com.coovane.bytetrix.common.util;

import java.util.Objects;

/**
 * <p>
 * 脱敏工具类
 * </p>
 *
 * @author: Hsu
 * @date: 2021/8/9 21:33
 * @copyright: companyName
 * @see
 * @since 1.8
 */
public class DesensitizeUtils {

    /**
     * 中国复姓
     */
    private static String[] COMPOUND_SURNAME = {"欧阳", "太史", "上官", "端木", "司马", "东方", "独孤", "南宫", "万俟", "闻人", "夏侯", "诸葛", "尉迟", "公羊", "赫连", "澹台",
            "皇甫", "宗政", "濮阳", "公冶", "太叔", "申屠", "公孙", "慕容", "仲孙", "钟离", "长孙", "宇文", "司徒", "鲜于", "司空", "闾丘", "子车",
            "亓官", "司寇", "巫马", "公西", "颛孙", "壤驷", "公良", "漆雕", "乐正", "宰父", "谷梁", "拓跋", "夹谷", "轩辕", "令狐", "段干", "百里",
            "呼延", "东郭", "南门", "羊舌", "微生", "公户", "公玉", "公仪", "梁丘", "公仲", "公上", "公门", "公山", "公坚", "左丘", "公伯", "西门",
            "公祖", "第五", "公乘", "贯丘", "公皙", "南荣", "东里", "东宫", "仲长", "子书", "子桑", "即墨", "达奚", "褚师", "吴铭"};

    public static void main(String[] args) {
        System.out.println("==========" + DesensitizeUtils.chineseName("欧阳锋", true));
        System.out.println("==========" + DesensitizeUtils.chineseName("欧阳锋", false));
    }

    /**
     * 对字符串进行脱敏操作
     *
     * @param origin          原始字符串
     * @param prefixNoMaskLen 左侧需要保留几位明文字段
     * @param suffixNoMaskLen 右侧需要保留几位明文字段
     * @param maskStr         用于遮罩的字符串, 如'*'
     * @return 脱敏后结果
     */
    public static String desensitizeValue(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
        if (origin == null) {
            return "";
        }

        StringBuilder builder = new StringBuilder();
        int maskMaxLen = 10;
        int currentMaskLen = 0;
        int originLen = origin.length();
        if(prefixNoMaskLen >= originLen){
            prefixNoMaskLen = suffixNoMaskLen = originLen / 3;
        }
        for (int i = 0, n = originLen; i < n; i++) {
            if (i < prefixNoMaskLen) {
                builder.append(origin.charAt(i));
                continue;
            }
            if (i > (n - suffixNoMaskLen - 1)) {
                builder.append(origin.charAt(i));
                continue;
            }
            // 遮罩最长不超过10
            if(currentMaskLen < maskMaxLen){
                builder.append(maskStr);
                currentMaskLen++;
            }
        }
        return builder.toString();
    }

    /**
     * 【中文姓名】李韶梦
     * keepSurname=false，只显示最后一个汉字，其他隐藏为星号，即**梦
     * keepSurname=true，保留姓氏，其他隐藏为星号，即李*梦
     * @param name 姓名
     * @param keepSurname 是否保留姓氏true-李*梦，false-**梦
     * @return 结果
     */
    public static String chineseName(String name,boolean keepSurname) {
        if (Objects.isNull(name) || name.trim().length() == 0) {
            return "";
        }
        int length = name.length();
        if(keepSurname){
            if (length < 2) {
                return name + "*";
            }
            String newName = name.substring(0, 2);
            boolean flag = false;
            for (int i = 0; i < COMPOUND_SURNAME.length; i++) {
                if (newName.equals(COMPOUND_SURNAME[i])) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                newName += "*";
            } else {
                newName = name.substring(0, 1)+"*";
            }
            return newName;
        }
        if(length > 3){
            name = name.substring(length - 3, length);
        }
        return desensitizeValue(name, 0, 1, "*");
    }

    /**
     * 【身份证号】显示前六位, 四位，其他隐藏。共计18位或者15位，比如：340304*******1234
     *
     * @param id 身份证号码
     * @return 结果
     */
    public static String idCardNum(String id) {
        return desensitizeValue(id, 6, 4, "*");
    }

    /**
     * 【固定电话】后四位，其他隐藏，比如 ****1234
     *
     * @param num 固定电话
     * @return 结果
     */
    public static String fixedPhone(String num) {
        return desensitizeValue(num, 0, 4, "*");
    }

    /**
     * 【手机号码】前三位，后四位，其他隐藏，比如135****6810
     *
     * @param num 手机号码
     * @return 结果
     */
    public static String mobilePhone(String num) {
        return desensitizeValue(num, 3, 4, "*");
    }

    /**
     * 【地址】只显示到地区，不显示详细地址，比如：北京市海淀区****
     *
     * @param address 地址
     * @return 结果
     */
    public static String address(String address) {
        return desensitizeValue(address, 6, 0, "*");
    }

    /**
     * 【电子邮箱 邮箱前缀仅显示第一个字母，前缀其他隐藏，用星号代替，@及后面的地址显示，比如：d**@126.com
     *
     * @param email 电子邮箱
     * @return 结果
     */
    public static String email(String email) {
        if (email == null) {
            return "";
        }
        int index = email.indexOf("@");
        if (index <= 1) {
            return email;
        }
        String preEmail = desensitizeValue(email.substring(0, index), 1, 0, "*");
        return preEmail + email.substring(index);

    }

    /**
     * 【银行卡号】前六位，后四位，其他用星号隐藏每位1个星号，比如：622260**********1234
     *
     * @param cardNum 银行卡号
     * @return 结果
     */
    public static String bankCard(String cardNum) {
        return desensitizeValue(cardNum, 6, 4, "*");
    }

    /**
     * 【密码】密码的全部字符都用*代替，比如：******
     *
     * @param password 密码
     * @return 结果
     */
    public static String password(String password) {
        if (password == null) {
            return "";
        }
        return "******";
    }

    /**
     * 【密钥】密钥除了最后三位，全部都用*代替，比如：***xdS
     * 脱敏后长度为6，如果明文长度不足三位，则按实际长度显示，剩余位置补*
     *
     * @param key 密钥
     * @return 结果
     */
    public static String key(String key) {
        if (key == null) {
            return "";
        }
        int viewLength = 6;
        StringBuilder tmpKey = new StringBuilder(desensitizeValue(key, 0, 3, "*"));
        if (tmpKey.length() > viewLength) {
            return tmpKey.substring(tmpKey.length() - viewLength);
        } else if (tmpKey.length() < viewLength) {
            int buffLength = viewLength - tmpKey.length();
            for (int i = 0; i < buffLength; i++) {
                tmpKey.insert(0, "*");
            }
            return tmpKey.toString();
        } else {
            return tmpKey.toString();
        }
    }

}
